<template>
  <basic-dialog
    :visible="visible"
    :title="title"
    align-center
    :loading="loading"
    width="max-content"
    @open="handleOpenDialog"
    @submit="handleSubmit"
    @closed="handleCloseDialog"
  >
    <el-form
      ref="formRef"
      :rules="rules"
      :model="formData"
      label-position="top"
      require-asterisk-position="right"
    >
      <el-form-item label="分组名称" prop="name">
        <el-input
          v-model="formData.name"
          maxlength="30"
          placeholder="请输入分组名称"
        ></el-input>
      </el-form-item>

      <el-form-item class="hidden" prop="domain_ids"></el-form-item>
      <basic-transfer
        v-if="visible"
        v-model="formData.domain_ids"
        class="mb-[18px]"
        :props="{ label: 'name', key: 'id', disabled: 'disabled' }"
        :loading="transferLoading"
        :data="domainList"
      ></basic-transfer>

      <el-form-item label="备注" prop="remark">
        <el-input
          v-model="formData.remark"
          class="w-full"
          maxlength="200"
          placeholder="请输入备注"
        ></el-input>
      </el-form-item>
    </el-form>
  </basic-dialog>
</template>

<script setup lang="ts">
import type { FormInstance, FormItemRule } from 'element-plus'
import type { Ref } from 'vue'

import type { CommonAPI } from '@/apis/model/_utils'
import type { DomainGroupModel, DomainModel } from '@/apis/model/domain'
import type { UserModel } from '@/apis/model/user'
import ToastUtils from '@/utils/toast'

interface IProps {
  visible: boolean
  loading?: boolean
  record?: DomainGroupModel | null
}

interface IEmit {
  (event: 'update:visible', val: boolean): void
  (event: 'update:loading', val: boolean): void
  (event: 'reload'): void
}

interface IFormData {
  user_id?: string
  name: string
  domain_ids: string[]
  remark: string
}

const emit = defineEmits<IEmit>()
const props = defineProps<IProps>()
const transferLoading = ref(false)

const title = computed(() => (props.record?.id ? '编辑分组' : '新建分组'))

const rules: Record<string, FormItemRule[]> = {
  name: [
    {
      required: true,
      message: '请输入分组名称',
      trigger: 'blur'
    }
  ]
}

const user = inject<Ref<UserModel | undefined>>('user') as Ref<
  UserModel | undefined
>

// 是否存在用户
const isExistUser = computed(() => !!user.value?.id)
// 是否编辑模式
const isEdit = computed(() => !!props.record?.id)

const formRef = ref<FormInstance>()
const formData = reactive<IFormData>({
  name: '',
  domain_ids: [],
  remark: ''
})

/**
 * 过滤域名分组
 * @param domain 域名
 */
const filterGroup = (domain: DomainModel) => {
  const userFlag = domain.group_id === '0'
  if (isExistUser.value) {
    if (isEdit.value) {
      return domain.group_id === props.record?.id || userFlag
    }
    return userFlag
  }
  const adminFlag = domain.admin_group_id === '0'
  if (isEdit.value) {
    return domain.admin_group_id === props.record?.id || adminFlag
  }
  return adminFlag
}

/**
 * 域名列表
 */
const domainList = ref<{ id: string; name: string }[]>([])
const getData = () => {
  transferLoading.value = true
  domainListApi({ offset: 0, limit: 0, user_id: user.value?.id })
    .then(res => {
      const list = res.list as DomainModel[]
      domainList.value = list
        .filter(filterGroup)
        .map(v => ({ id: v.id!, name: v.name! }))
      formData.domain_ids = list
        .filter(
          v =>
            v.group_id === props.record?.id ||
            v.admin_group_id === props.record?.id
        )
        .map(v => v.id!)
    })
    .finally(() => {
      transferLoading.value = false
    })
}
watch(
  () => props.visible,
  newVal => {
    if (newVal) {
      getData()
    }
  }
)

/**
 * 处理表单提交
 */
const handleSubmit = async () => {
  await formRef.value?.validate()
  const data = { ...formData }
  if (user.value) {
    data.user_id = user.value.id
  }
  if (!props.record) {
    // 新增
    handleSave(
      isExistUser.value ? postUserDomainGroupApi : postDomainGroupApi,
      data
    )
  } else {
    // 编辑
    handleSave(
      isExistUser.value ? putUserDomainGroupApi : putDomainGroupApi,
      data
    )
  }
}

/**
 * 保存
 */
const handleSave = async (
  fn:
    | CommonAPI<'/v1/domain_group', 'post'>
    | CommonAPI<'/v1/domain_group/{id}', 'put'>
    | CommonAPI<'/v1/admin_domain_group', 'post'>
    | CommonAPI<'/v1/admin_domain_group/{id}', 'put'>,
  data: IFormData
) => {
  emit('update:loading', true)
  try {
    await fn({
      id: props.record?.id as string,
      ...data
    })
    ToastUtils.success(props.record?.id ? '修改成功' : '创建成功')
    emit('reload')
    handleCloseDialog()
  } finally {
    emit('update:loading', false)
  }
}

/**
 * dialog 打开，做重新赋值操作
 */
const handleOpenDialog = () => {
  if (props.record) {
    formData.name = props.record.name as string
    formData.remark = props.record.remark as string
  }
}

/**
 * dialog关闭
 */
const handleCloseDialog = () => {
  emit('update:visible', false)
  emit('update:loading', false)
  formRef.value?.resetFields()
}
</script>

<style scoped lang="scss"></style>
